Skip to content

[eas-cli] Add --refresh-distribution-certificate for non-intractive builds #3739

Open
sswrk wants to merge 6 commits into
szymonswierk/non-interactive-build-provisioning-profile-validationa-and-refresh-best-effortfrom
szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in
Open

[eas-cli] Add --refresh-distribution-certificate for non-intractive builds #3739
sswrk wants to merge 6 commits into
szymonswierk/non-interactive-build-provisioning-profile-validationa-and-refresh-best-effortfrom
szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in

Conversation

@sswrk
Copy link
Copy Markdown
Contributor

@sswrk sswrk commented May 18, 2026

Why

When there's no valid distribution certificate associated with an app, and a non-interactive development build is run (e.g. invoked by CI or by a workflow job), even without the freeze-credentials flag, the distribution certificate is not validated or refreshed, which may fail the internal build and require doing manual eas build to create a new certificate. See the Linear issue: https://linear.app/expo/issue/ENG-21330/make-it-possible-to-refresh-a-distribution-certificate-in-non

How

Added an opt-in distribution certificate refresh to non-interactive builds with flag --refresh-distribution-certificate.

When the flag is present, we hit www GQL API to get the ASC API key (the submission key), and we distribution certificate validation or set-up if needed. packages/eas-cli/src/credentials/ios/actions/SetUpDistributionCertificate.ts is where this logic happens.

The flag mustn't be present when --freeze-credentials is present, these are conflicting flags.

I'm leaning towards an opt-in flag instead of extending the default behavior because of the extra credentials configuration requirements and side effects of the distribution certificate refresh logic.

Test Plan

Added unit tests.

Manual verification:

  • Did easd build --platform ios --profile development --non-interactive --refresh-distribution-certificate in the following scenarios, verified it works:
    • current certificate is valid
    • current certificate is invalid
  • Did easd build --platform ios --profile development --non-interactive --refresh-distribution-certificate --refresh-ad-hoc-provisioning-profile, verified the ASC API key got resolved just once.

@linear
Copy link
Copy Markdown

linear Bot commented May 18, 2026

ENG-21330

Copy link
Copy Markdown
Contributor Author

sswrk commented May 18, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@sswrk sswrk changed the title [eas-cli] Add --refresh-distribution-certificate for non-intractive builds [eas-cli] Add --refresh-distribution-certificate for non-intractive builds May 18, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

❌ Patch coverage is 77.77778% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.99%. Comparing base (dc5b262) to head (a19376a).

Files with missing lines Patch % Lines
packages/eas-cli/src/commands/build/index.ts 0.00% 2 Missing and 3 partials ⚠️
...ntials/ios/actions/SetUpDistributionCertificate.ts 89.66% 2 Missing and 1 partial ⚠️
packages/eas-cli/src/build/createContext.ts 0.00% 1 Missing ⚠️
...tials/ios/actions/SetUpAdhocProvisioningProfile.ts 83.34% 1 Missing ⚠️
Additional details and impacted files
@@                                                       Coverage Diff                                                       @@
##           szymonswierk/non-interactive-build-provisioning-profile-validationa-and-refresh-best-effort    #3739      +/-   ##
===============================================================================================================================
+ Coverage                                                                                        57.86%   57.99%   +0.13%     
===============================================================================================================================
  Files                                                                                              913      913              
  Lines                                                                                            39622    39646      +24     
  Branches                                                                                          8296     8311      +15     
===============================================================================================================================
+ Hits                                                                                             22925    22987      +62     
+ Misses                                                                                           15242    15207      -35     
+ Partials                                                                                          1455     1452       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sswrk sswrk marked this pull request as ready for review May 18, 2026 13:24
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 18, 2026

Subscribed to pull request

File Patterns Mentions
**/* @douglowder
packages/eas-cli/src/commands/build/** @sjchmiela
packages/eas-cli/src/build/** @sjchmiela

Generated by CodeMention

@sswrk sswrk requested review from quinlanj and sjchmiela May 18, 2026 13:27
@sswrk sswrk force-pushed the szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in branch from 763d237 to 1e21106 Compare May 20, 2026 11:43
@sswrk sswrk force-pushed the szymonswierk/eng-7041-allow-including-all-eas-registered-devices-automatically-in branch 2 times, most recently from 701b7d7 to 4c939d9 Compare May 20, 2026 11:57
@sswrk sswrk force-pushed the szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in branch 2 times, most recently from 354509c to e1e9a7e Compare May 20, 2026 12:01
Copy link
Copy Markdown
Member

@quinlanj quinlanj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. I'm surprised this was a feature people asked for because the number of dist certs apple lets you have in your account is very low (2-3 max)

Comment thread packages/eas-cli/src/credentials/ios/actions/SetUpDistributionCertificate.ts Outdated
Comment thread packages/eas-cli/src/credentials/ios/actions/SetUpDistributionCertificate.ts Outdated
@sswrk sswrk force-pushed the szymonswierk/eng-7041-allow-including-all-eas-registered-devices-automatically-in branch from d20291d to d4b4bf6 Compare May 21, 2026 11:37
@sswrk sswrk force-pushed the szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in branch from e1e9a7e to 6436e27 Compare May 21, 2026 11:37
@sswrk sswrk changed the base branch from szymonswierk/eng-7041-allow-including-all-eas-registered-devices-automatically-in to graphite-base/3739 May 21, 2026 12:04
throw new Error(
'No App Store Connect API Key found for distribution certificate refresh. In non-interactive mode, provide one via:\n' +
' - Environment variables: EXPO_ASC_API_KEY_PATH, EXPO_ASC_KEY_ID, EXPO_ASC_ISSUER_ID\n' +
' - EAS credentials service: configure an App Store Connect API Key for submissions on this app'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh it's still weird to me we're saying to use key for submissions to generate certificates

Comment thread packages/eas-cli/src/credentials/ios/actions/SetUpDistributionCertificate.ts Outdated
Log.log(`Reusing distribution certificate with serial number ${cert.serialNumber}`);
return cert;
}
return await this.createNewDistCertAsync(ctx);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how likely is that we're going to hit

if (ctx.nonInteractive) {
throw new Error(
"Start the CLI without the '--non-interactive' flag to revoke existing certificates."
);
}
often? can we do something about it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're going to hit this when a new certificate needs to be created and there are already 3 (non-matching, e.g. for different teams) certificates in the Apple account. I don't think we should do anything automatically in this case, as this would involve revoking unrelated certs. We could make an opt-in flag to "force override" a cert.

@sswrk sswrk force-pushed the szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in branch from 6436e27 to 424bd35 Compare June 3, 2026 08:30
@sswrk sswrk force-pushed the graphite-base/3739 branch from d4b4bf6 to 15311b5 Compare June 3, 2026 08:30
@sswrk sswrk changed the base branch from graphite-base/3739 to szymonswierk/non-interactive-build-provisioning-profile-validationa-and-refresh-best-effort June 3, 2026 08:30
sswrk added 3 commits June 3, 2026 10:38
…fort

Remove the --refresh-distribution-certificate opt-in flag and validate or
refresh distribution certificates automatically in non-interactive builds,
reusing tryAuthenticateAppStoreWithEasAscApiKeyAsync from the parent stack.
@sswrk sswrk force-pushed the szymonswierk/eng-21330-make-it-possible-to-refresh-a-distribution-certificate-in branch from 424bd35 to 0d88201 Compare June 3, 2026 08:38
@sswrk sswrk force-pushed the szymonswierk/non-interactive-build-provisioning-profile-validationa-and-refresh-best-effort branch from 15311b5 to dc5b262 Compare June 3, 2026 08:38
@sswrk sswrk changed the title [eas-cli] Add --refresh-distribution-certificate for non-intractive builds [eas-cli] Validate/regenerate/create distribution certificate in non-interactive iOS builds using submission ASC API key when present Jun 3, 2026
@sswrk
Copy link
Copy Markdown
Contributor Author

sswrk commented Jun 3, 2026

Changed this to follow the "best effort" approach like provisioning profiles in #3805 instead of being opt-in with a flag, as I don't see any downsides of just attempting to do the validation when an ASC API key is available in EAS. If we were to do something like "force setup dist cert even if some other unrelated (other apple team) cert needs to be revoked", that would be an opt-in flag for special use cases.

@quinlanj Apologies, re-requesting review.

@sswrk sswrk requested a review from quinlanj June 3, 2026 09:42
Copy link
Copy Markdown
Member

@quinlanj quinlanj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks beautiful, I'd push back on this from a product perspective though. For a lot of developers, distribution certs are often treated like account-wide signing infrastructure, rather than app-local disposable state. I suspect there will be users who will be unpleasantly surprised to discover the submission API key was used as implicit consent to create signing certs in non interactive mode.

My vote is to put this behind the original flag you had unless you felt strongly about this

@sswrk sswrk changed the title [eas-cli] Validate/regenerate/create distribution certificate in non-interactive iOS builds using submission ASC API key when present [eas-cli] Add --refresh-distribution-certificate for non-intractive builds Jun 3, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

✅ Thank you for adding the changelog entry!

@sswrk
Copy link
Copy Markdown
Contributor Author

sswrk commented Jun 3, 2026

[...] My vote is to put this behind the original flag you had unless you felt strongly about this

This is some amazing feedback, thank you. Reverting this to the opt-in approach, I'm happy to lean on your expertise

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants